module WegoLint; end

require 'singleton'

class WegoLint::RuleRegistry
  include Singleton

  @@rule_count = 0

  def self.rule_count
    @@rule_count
  end

  def self.rule_count=(rule_count)
    @@rule_count = rule_count
  end

  attr_accessor :language_context, :rules

  def initialize
    @rule_id = 0
    @rules = {}
    @language_context = :general
  end

  def find_by_description(description)
    rules.keys.each do |ruleset|
      match = rules[ruleset].keys.find { |key| key == description }
      return rules[ruleset][match] if match
    end
    nil
  end

  def load_rules
    local_rules_dir = File.dirname(__FILE__) + '/../../rules/'
    Dir[local_rules_dir + '*'].each { |rule| require rule }

    rules_directory = ENV["HOME"] + '/.wegolint'
    standard_rules_directory = rules_directory + '/standard'
    FileUtils.mkdir_p rules_directory
    FileUtils.mkdir_p standard_rules_directory
    Dir[rules_directory + '/**/*.rb'].each { |rule| require rule }
  end

  # Pattern stolen from rspec
  def add_rule(description, block)
    WegoLint::RuleRegistry::rule_count += 1
    klass = WegoLint::RuleRegistry.
      const_set("Rule_#{WegoLint::RuleRegistry::rule_count}",
                subclass(WegoLint::Rule, block))
    @rules[@language_context] = {} unless @rules[@language_context]
    rule = klass.new(description, @language_context)
    @rules[@language_context][description] = rule
    rule
  end

  private

  def subclass(parent, block)
    subclass = Class.new(parent)
    subclass.send(:extend, WegoLint::DSL::RuleDirectives.clone)
    subclass.module_eval(&block) if block
    subclass
  end
end
